﻿using System;
using System.Collections;
using System.Collections.Specialized;
using System.IO;
using System.Text;

using CodeSmith.Engine;
using dotNails.CodeGen.Util;

namespace dotNails.CodeGen.Models {
	/// <summary>
	/// Summary description for CodeBlock.
	/// </summary>
	public class CodeBlock {
		#region Constructors
		public CodeBlock() {}
		#endregion Constructors

		#region Properties
		//private string _namespace = string.Empty;
		//public string Namespace {
		//    get { return _namespace; }
		//    set { _namespace = value; }
		//}
		
		//private string _class = string.Empty;
		//public string Class {
		//    get { return _class; }
		//    set { _class = value; }
		//}

		// TODO: Change to pull this from config or some source by convention (like a template folder off of the project root)
		//private string _templateFolder = @"e:\development\opensource\dotnails\dotnails\templates";
		//public string TemplateFolder {
		//    get { 
		//        //return _templateFolder;
		//        //return AppDomain.CurrentDomain.BaseDirectory;
		//        string folder = this.GetType().Module.Assembly.Location;
		//        LogUtil.EventLogMessage("Assembly folder is - " + folder);
		//        return folder;
		//    }
		//    //set { _templateFolder = value; }
		//}

		private string _templatePath = string.Empty;
		public string TemplatePath {
			get {
				if (string.IsNullOrEmpty(_templatePath)) {
					_templatePath = Microsoft.Win32.Registry.GetValue(@"HKEY_LOCAL_MACHINE\Software\dotNails", "TemplatePath", string.Empty).ToString();
					if (string.IsNullOrEmpty(_templatePath)) {
						throw new Exception(@"TemplatePath not found or is null in registry: HKEY_LOCAL_MACHINE\Software\dotNails\TemplatePath");
					}
				}
				return _templatePath;
			}
			set {
				_templatePath = value;
			}
		}

		private string _templateFileName = string.Empty;
		public string TemplateFileName {
			get { return _templateFileName; }
			set { _templateFileName = value; }
		}

		private string _region = string.Empty;
		public string Region {
			get { return _region; }
			set { _region = value; }
		}
		#endregion Properties

		public virtual string Render() {
			BaseCodeTemplate template = new BaseCodeTemplate();
			StringBuilder output = new StringBuilder();
			StringWriter stringWriter = new StringWriter(output);

			CodeTemplateCompiler compiler = new CodeTemplateCompiler(TemplateFileName);
			compiler.Compile();

			if (compiler.Errors.Count == 0) {
				template = (BaseCodeTemplate)compiler.CreateInstance();
			}
			else {
				for (int i = 0; i < compiler.Errors.Count; i++) {
					LogUtil.EventLogMessage("Codesmith compiler error with file - " + TemplateFileName);
					output.Append(compiler.Errors[i].ToString());
				}
				throw new Exception(output.ToString());
			}

			if (template != null) {
				// Sets properties on our template from our NameValueCollection
				PopulateTemplate(template);

				template.Render(stringWriter);
			}
			
			return output.ToString();
		}

		public virtual void PopulateTemplate(BaseCodeTemplate template) {
			//template.Namespace = Namespace;
			//template.EntityClass = Class;
		}

	}
}